﻿Imports FairShop.Helpers
Imports System.ComponentModel

Public Class BeheerArtikelForm

    ' TODO: evt. Artikel.Voorraad ook binden aan udAantal (nu wordt het met een methode bijgewerkt)

    Const DEFAULT_VOORRAAD As Integer = 1
    Const DEFAULT_BTW As Double = 21.0 ' TODO: als configuratie kunnen instellen

    Private _barcodeHasFocus As Boolean = False
    Private _modus As Modus
    Private _myArtikelRow As ArtikelsDataSet.ArtikelsRow

    Private Enum Modus
        NieuwArtikel
        BestaandArtikel
    End Enum

    Public Enum ArtikelSoortType
        Artikel
        Doos
    End Enum

    Public Enum Context
        Inventaris    ' laat toe de voorraad van artikels in te geven
        Levering      ' laat toe bij een levering het geleverd aantal in te geven
        BeheerArtikel ' laat toe artikel te beheren
    End Enum

    Public ReadOnly Property ArtikelId() As Integer
        Get
            If (_myArtikelRow IsNot Nothing) Then
                Return _myArtikelRow.Id
            Else
                Return 0
            End If
        End Get
    End Property

    Public Property Aantal() As Integer
        Get
            Return _myArtikelRow.Voorraad
        End Get
        Set(ByVal value As Integer)
            _myArtikelRow.Voorraad = value
        End Set
    End Property

    Public ReadOnly Property ArtikelSoort() As ArtikelSoortType
        Get
            If TabControl1.SelectedTab Is TabPageDoos Then
                Return ArtikelSoortType.Doos
            Else
                Return ArtikelSoortType.Artikel
            End If
        End Get
    End Property

#Region "Constructors"

    ''' <summary>
    ''' Constructor voor toevoegen nieuw artikel buiten inventaris of levering
    ''' </summary>
    Public Sub New()
        InitForm(Context.BeheerArtikel, Utility.Data)
        InitArtikelRow("", DEFAULT_VOORRAAD, Utility.Data)
        Dim position As Integer = Utility.Data.Artikels.Rows.IndexOf(_myArtikelRow)
        Me.ArtikelsBindingSource.Position = position
    End Sub

    ''' <summary>
    ''' Constructor voor toevoegen van nieuw artikel vanuit inventaris
    ''' </summary>
    ''' <param name="barCode">barcode van toe te voegen artikel</param>
    ''' <param name="aantalVoorraad">Aantal reeds in te vullen als voorraad</param>
    Public Sub New(ByVal barCode As String, ByVal aantalVoorraad As Integer)
        InitForm(Context.Inventaris, Utility.Data)
        InitArtikelRow(barCode, aantalVoorraad, Utility.Data)
        Dim position As Integer = Utility.Data.Artikels.Rows.IndexOf(_myArtikelRow)
        Me.ArtikelsBindingSource.Position = position
    End Sub

    ''' <summary>
    ''' Constructor voor toevoegen van nieuw artikel vanuit levering (artikel stelt leveringsdetail voor)
    ''' </summary>
    ''' <param name="barCode">barcode van toe te voegen artikel</param>
    ''' <param name="aantalLevering">Aantal reeds in te vullen als geleverd</param>
    ''' <param name="ds">Dataset</param>
    Public Sub New(ByVal barCode As String, ByVal aantalLevering As Integer, ByVal ds As ArtikelsDataSet)
        InitForm(Context.Levering, ds)
        InitArtikelRow(barCode, aantalLevering, ds)
        Dim position As Integer = ds.Artikels.Rows.IndexOf(_myArtikelRow)
        Me.ArtikelsBindingSource.Position = position
    End Sub

    ''' <summary>
    ''' Constructor voor het bijwerken van een bestaand artikel
    ''' </summary>
    ''' <param name="idArtikel"></param>
    ''' <param name="con"></param>
    ''' <remarks></remarks>
    Public Sub New(ByVal idArtikel As Integer, ByVal con As Context)
        InitForm(con, Utility.Data)
        _myArtikelRow = Utility.Data.Artikels.FindById(idArtikel)
        Dim position As Integer = Utility.Data.Artikels.Rows.IndexOf(_myArtikelRow)
        Me.ArtikelsBindingSource.Position = position

        _modus = Modus.BestaandArtikel
        TabControl1.TabPages.Remove(TabPageDoos) ' doos heeft geen zin bij wijzigen
        Me.Text = "Artikel wijzigen"
    End Sub

    ''' <summary>
    ''' Constructor voor bijwerken van artikel dat een leveringsdetail voorstelt bij een levering
    ''' </summary>
    ''' <param name="idArtikel"></param>
    ''' <param name="ds"></param>
    Public Sub New(ByVal idArtikel As Integer, ByVal ds As ArtikelsDataSet)
        InitForm(Context.Levering, ds)
        _myArtikelRow = ds.Artikels.FindById(idArtikel)
        Dim position As Integer = ds.Artikels.Rows.IndexOf(_myArtikelRow)
        Me.ArtikelsBindingSource.Position = position

        _modus = Modus.BestaandArtikel
        TabControl1.TabPages.Remove(TabPageDoos) ' doos heeft geen zin bij wijzigen
        Me.Text = "Artikel wijzigen"
    End Sub

    Private Sub InitForm(ByVal con As Context, ByVal ds As ArtikelsDataSet)
        InitializeComponent()

        Me.ArtikelsBindingSource.DataSource = ds
        Me.LeveranciersBindingSource.DataSource = Utility.Data
        Me.CategorieenBindingSource.DataSource = Utility.Data
        Select Case con
            Case Context.Inventaris
                Me.VoorraadLabel.Visible = True
                Me.VoorraadLabel.Text = "Voorraad: "
                Me.VoorraadTextBox.Visible = True
                Me.VoorraadStuksLabel.Visible = True

                Me.VerwachteVoorraadLabel.Visible = True
                Me.VerwachteVoorraadLabel.Text = "Verwachte voorraad: "
                Me.VerwachteVoorraadTextBox.Visible = True
                Me.VerwachteVoorraadTextBox.Enabled = False
                Me.VerwachtStuksLabel.Visible = True
                Me.LabelAantalDozen.Text = "Voorraad: "
            Case Context.Levering
                Me.VoorraadLabel.Visible = True
                Me.VoorraadLabel.Text = "Geleverd: "
                Me.VoorraadTextBox.Visible = True
                Me.VoorraadStuksLabel.Visible = True

                Me.VerwachteVoorraadLabel.Visible = False
                Me.VerwachteVoorraadTextBox.Visible = False
                Me.VerwachtStuksLabel.Visible = False
                Me.LabelAantalDozen.Text = "Geleverd: "
            Case Context.BeheerArtikel
                ' de voorraad is het aantal zoals het de laatste keer geteld is.
                ' bij het wijzigen van een artikel passen we de VerwachteVoorraad aan.
                Me.VoorraadLabel.Visible = False
                Me.VoorraadTextBox.Visible = False
                Me.VoorraadStuksLabel.Visible = False

                Me.VerwachteVoorraadLabel.Visible = True
                Me.VerwachteVoorraadTextBox.Visible = True
                Me.VerwachteVoorraadTextBox.Enabled = True
                Me.VerwachteVoorraadTextBox.Enabled = True
                Me.VerwachteVoorraadLabel.Text = "Voorraad: "
                Me.VerwachtStuksLabel.Visible = True
                Me.LabelAantalDozen.Text = "Voorraad: "
                Me.udAantal.DataBindings.Clear() ' niet binden aan Voorraad, maar aan VerwachteVoorraad
                Me.udAantal.DataBindings.Add(New Binding("Value", Me.ArtikelsBindingSource, "VerwachteVoorraad", True))
        End Select

        TabPageArtikel.CausesValidation = False
        TabPageDoos.CausesValidation = False
    End Sub

    Private Sub InitArtikelRow(ByVal barCode As String, ByVal aantal As Integer, ByVal ds As ArtikelsDataSet)
        Dim defaultArtikelCode As String = "wwa"
        If (barCode IsNot Nothing AndAlso barCode.Length > 5) Then
            ' neem 6e tot voorlaatste cijfer van barcode als default artikelcode
            ' geeft wel risico op dubbels, maar artikelcode is niet essentieel, id wel
            defaultArtikelCode &= barCode.Substring(barCode.Length - 6, 5)
            DozenToevoegControl1.BarcodeDoos = barCode
        End If
        '_myArtikelRow = ds.Artikels.AddArtikelsRow("", _
        '     defaultArtikelCode, barCode, True, aantal, 1, 0, 0, 0, _
        '     DEFAULT_BTW, defaultLeverancier, False, False, defaultCategorie, 0, 0S, DateTime.Now())
        _myArtikelRow = ds.Artikels.NewArtikelsRow()
        _myArtikelRow.Omschrijving = ""
        _myArtikelRow.Artikelcode = defaultArtikelCode
        _myArtikelRow.Barcode = barCode
        _myArtikelRow.Verkoopbaar = True
        _myArtikelRow.Voorraad = aantal
        _myArtikelRow.AantalPerVerpakking = 1
        _myArtikelRow.Prijs = 0
        _myArtikelRow.StatiegeldEuro = 0
        _myArtikelRow.Inkoopprijs = 0
        _myArtikelRow.BTW = DEFAULT_BTW
        _myArtikelRow.IdLeverancier = Constants.DEFAULT_LEVERANCIER_ID
        _myArtikelRow.IsLeeggoed = False
        _myArtikelRow.IsCheque = False
        _myArtikelRow.IdCategorie = Constants.DEFAULT_CATEGORIE_ID
        _myArtikelRow.VerwachteVoorraad = 0
        '_myArtikelRow.KortingLeverancier = 0S
        _myArtikelRow.SetKortingLeverancierNull()
        '_myArtikelRow.DatumToegevoegd = DateTime.Now()
        ds.Artikels.AddArtikelsRow(_myArtikelRow)

        _modus = Modus.NieuwArtikel
        Me.Text = "Artikel toevoegen"
    End Sub

    Protected Overrides Sub OnLoad(ByVal e As EventArgs)
        MyBase.OnLoad(e)
        If (_modus = Modus.NieuwArtikel) Then
            Me.PrijsTextBox.Text = "" ' verplichten in te vullen
        End If
        Me.ArtikelcodeTextBox.MaxLength = Utility.Data.Artikels.ArtikelcodeColumn.MaxLength
        Me.OmschrijvingTextBox.MaxLength = Utility.Data.Artikels.OmschrijvingColumn.MaxLength
        Me.BarcodeTextBox.MaxLength = 13
        'Me.TabPageArtikel.Focus() ' doet niets, focus gaat naar OK-button???
        'Me.OmschrijvingTextBox.Focus() ' doet niets, focus gaat naar OK-button???
    End Sub

#End Region

#Region "Event handling"

    Protected Overrides Sub OnKeyUp(ByVal e As KeyEventArgs)
        MyBase.OnKeyUp(e)
        Select Case e.KeyCode
            Case Keys.F2
                btnOK_Click(Me, EventArgs.Empty)
        End Select
    End Sub

    Private Sub btnOK_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnOK.Click
        If (TabControl1.SelectedTab Is TabPageArtikel) Then
            If (_barcodeHasFocus) Then
                ' bij het inscannen van de barcode wordt een Enter gegenereerd
                ' zorg ervoor dat deze het scherm niet sluit
                Me.DialogResult = DialogResult.None
                Me.PrijsTextBox.Focus()
                Return
            End If
            If (Not Me.ValidateChildren(ValidationConstraints.Visible)) Then
                Me.DialogResult = DialogResult.None
                Return
            Else
                Me.DialogResult = DialogResult.OK
                'Update the dataset.   
                Try
                    Me.ArtikelsBindingSource.EndEdit()
                Catch ex As Exception
                    ' anders blijft bij inconsistente gegevens de rij toch staan in het InventarisForm
                    If (_myArtikelRow IsNot Nothing) Then
                        '_myArtikelRow.Delete()
                        _myArtikelRow.RejectChanges()
                    End If
                End Try

                ' ' met het volgende wordt direct in de databank bewaard. Zonder dit wordt alleen de meegegeven dataset bijgewerkt
                'If Not Me.ArtikelsTableAdapter.Update(Me.ArtikelsDataSet.Artikels) > 0 Then
                '    MessageBox.Show("Er werden geen artikels bijgewerkt.")
                'End If
            End If
        Else
            ' doos
            If (Not Me.ValidateChildren(ValidationConstraints.Visible)) Then
                Me.DialogResult = DialogResult.None
                Return
            End If
            Try
                Cursor = Cursors.WaitCursor
                Me.ArtikelsBindingSource.EndEdit()
                SamengesteldeArtikelsDal.AddDozen(_myArtikelRow, DozenToevoegControl1.BarcodeArtikel, DozenToevoegControl1.AantalArtikelsPerDoos, _
                                                  Convert.ToInt32(udAantal.Value))
                Me.DialogResult = DialogResult.OK
            Catch ex As Exception
                'lblInfo.Text = ex.Message
                MessageBox.Show(ex.Message, "Fout", MessageBoxButtons.OK, MessageBoxIcon.Error)
                log.WriteError("BeheerArtikelForm.btnOK_Click", ex)
                ' zorg ervoor dat deze het scherm niet sluit
                Me.DialogResult = DialogResult.None
            Finally
                Cursor = Cursors.Default
            End Try
        End If
    End Sub

    Protected Overrides Sub OnFormClosing(ByVal e As FormClosingEventArgs)
        MyBase.OnFormClosing(e)
        Select Case Me.DialogResult
            Case Windows.Forms.DialogResult.OK
                If (TabControl1.SelectedTab Is TabPageDoos) Then
                    CancelArtikelChanges()
                End If
            Case Windows.Forms.DialogResult.Cancel
                CancelArtikelChanges()
        End Select
    End Sub

    Private Sub BarcodeTextBox_Enter(ByVal sender As Object, ByVal e As EventArgs) Handles BarcodeTextBox.Enter
        _barcodeHasFocus = True
    End Sub

    Private Sub BarcodeTextBox_Leave(ByVal sender As Object, ByVal e As EventArgs) Handles BarcodeTextBox.Leave
        _barcodeHasFocus = False
    End Sub

    Private Sub IdCategorieListBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles IdCategorieListBox.SelectedIndexChanged
        ' TODO: dit zou beter bij in de categorietabel zitten (future proof)
        If (IdCategorieListBox.SelectedIndex >= 0) Then
            Dim selectedText As String = DirectCast(IdCategorieListBox.SelectedItem, DataRowView).Item(IdCategorieListBox.DisplayMember).ToString()
            If (selectedText.Contains("0%")) Then
                BTWTextBox.Text = "0"
            End If
            If (selectedText.Contains("6%")) Then
                BTWTextBox.Text = "6"
            End If
            If (selectedText.Contains("21%")) Then
                BTWTextBox.Text = "21"
            End If
        End If
    End Sub

    Private Sub IdLeverancierListBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles IdLeverancierListBox.SelectedIndexChanged
        If (IdLeverancierListBox.SelectedIndex >= 0) Then
            Dim selectedText As String = DirectCast(IdLeverancierListBox.SelectedItem, DataRowView).Item(IdLeverancierListBox.DisplayMember).ToString()
            Select Case selectedText.ToUpper()
                Case "UNICEF"
                    BTWTextBox.Text = "0"
                Case "ECOBOS"
                    BTWTextBox.Text = "21"
            End Select
        End If
    End Sub

    Private Sub TabControl1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles TabControl1.SelectedIndexChanged
        If (TabControl1.SelectedTab Is TabPageDoos) Then
            PanelArtikel.Visible = False ' zorgt ervoor dat hiervoor geen validatie meer afgaat
            PanelDoos.Visible = True
            DozenToevoegControl1.Focus()
        Else
            PanelDoos.Visible = False ' zorgt ervoor dat hiervoor geen validatie meer afgaat
            PanelArtikel.Visible = True
            'Me.ArtikelcodeTextBox.Focus()
            Me.OmschrijvingTextBox.Focus()
        End If
    End Sub

#Region "Validating events"

    Private Sub PrijsTextBox_Validating(ByVal sender As Object, ByVal e As CancelEventArgs) Handles PrijsTextBox.Validating
        If (Not PrijsTextBox.Visible) Then Return
        Dim fout As String = Nothing
        Dim prijs As Decimal
        If (Decimal.TryParse(PrijsTextBox.Text, prijs)) Then
            e.Cancel = False
        Else
            e.Cancel = True
            fout = "Geen geldige prijs"
        End If
        Me.ErrorProvider1.SetError(PrijsTextBox, fout)
    End Sub

    Private Sub ArtikelcodeTextBox_Validating(ByVal sender As Object, ByVal e As CancelEventArgs) Handles ArtikelcodeTextBox.Validating
        If (Not ArtikelcodeTextBox.Visible) Then Return
        Dim fout As String = Nothing
        If (ArtikelcodeTextBox.Text.Length = 0) Then
            e.Cancel = True
            fout = "Geen geldige artikelcode"
        End If
        Me.ErrorProvider1.SetError(ArtikelcodeTextBox, fout)
    End Sub

    Private Sub OmschrijvingTextBox_Validating(ByVal sender As Object, ByVal e As CancelEventArgs) Handles OmschrijvingTextBox.Validating
        If (Not OmschrijvingTextBox.Visible) Then Return
        Dim fout As String = Nothing
        If (OmschrijvingTextBox.Text.Length = 0) Then
            e.Cancel = True
            fout = "Geen geldige omschrijving"
        End If
        Me.ErrorProvider1.SetError(OmschrijvingTextBox, fout)
    End Sub

    Private Sub BarcodeTextBox_Validating(ByVal sender As Object, ByVal e As CancelEventArgs) Handles BarcodeTextBox.Validating
        If (Not BarcodeTextBox.Visible) Then Return
        Dim fout As String = Nothing
        If (Not BarcodeHelper.IsValid(BarcodeTextBox.Text)) Then
            e.Cancel = True
            fout = "Geen geldige barcode"
        End If
        Me.ErrorProvider1.SetError(BarcodeTextBox, fout)
    End Sub

#End Region

#End Region

#Region "Private methods"

    Private Sub CancelArtikelChanges()
        ' annuleer de wijzigingen in de artikel-tab
        Me.ArtikelsBindingSource.CancelEdit()
        If (_modus = Modus.NieuwArtikel) Then
            ' zorg ervoor dat het nieuw aangemaakte record verdwijnt
            ' doe dit alleen voor nieuwe records, anders worden de wijzigingen die tevoren
            ' gedaan werden in de DataSet-rij ook ongedaan gemaakt
            _myArtikelRow.RejectChanges()
        End If
    End Sub

#End Region

End Class